home *** CD-ROM | disk | FTP | other *** search
/ Aminet 37 / Aminet 37 (2000)(Schatztruhe)[!][Jun 2000].iso / Aminet / dev / lang / sofa.lha / sofa / smalleiffel / lib_se / compound.e < prev    next >
Text File  |  2000-03-25  |  8KB  |  331 lines

  1. --          This file is part of SmallEiffel The GNU Eiffel Compiler.
  2. --          Copyright (C) 1994-98 LORIA - UHP - CRIN - INRIA - FRANCE
  3. --            Dominique COLNET and Suzanne COLLIN - colnet@loria.fr
  4. --                       http://SmallEiffel.loria.fr
  5. -- SmallEiffel is  free  software;  you can  redistribute it and/or modify it
  6. -- under the terms of the GNU General Public License as published by the Free
  7. -- Software  Foundation;  either  version  2, or (at your option)  any  later
  8. -- version. SmallEiffel is distributed in the hope that it will be useful,but
  9. -- WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
  10. -- or  FITNESS FOR A PARTICULAR PURPOSE.   See the GNU General Public License
  11. -- for  more  details.  You  should  have  received a copy of the GNU General
  12. -- Public  License  along  with  SmallEiffel;  see the file COPYING.  If not,
  13. -- write to the  Free Software Foundation, Inc., 59 Temple Place - Suite 330,
  14. -- Boston, MA 02111-1307, USA.
  15. --
  16. class COMPOUND
  17.    --
  18.    -- A list of Eiffel instructions.
  19.    --
  20.  
  21. inherit GLOBALS;
  22.  
  23. creation make, from_compound
  24.  
  25. feature
  26.  
  27.    header_comment: COMMENT;
  28.  
  29. feature {NONE}
  30.  
  31.    current_type: TYPE;
  32.          -- Not Void when checked.
  33.  
  34. feature {COMPOUND}
  35.  
  36.    first_one: INSTRUCTION;
  37.          -- The `first_one' if any.
  38.  
  39.    remainder: FIXED_ARRAY[INSTRUCTION];
  40.          -- Non Void when the list has more than one element.
  41.  
  42. feature {NONE}
  43.  
  44.    make(hc: like header_comment; fo: like first_one; r: like remainder) is
  45.       require
  46.          hc /= Void or else fo /= Void;
  47.          r /= Void implies fo /= Void
  48.       do
  49.          header_comment := hc;
  50.          first_one := fo;
  51.          remainder := r;
  52.       ensure
  53.          header_comment = hc;
  54.          first_one = fo;
  55.          remainder = r
  56.       end;
  57.  
  58.    from_compound(c: like Current) is
  59.       require
  60.          c /= Void
  61.       do
  62.          header_comment := c.header_comment;
  63.          first_one := c.first_one;
  64.          remainder := c.remainder;
  65.          if remainder /= Void then
  66.             remainder := remainder.twin;
  67.          end;
  68.       ensure
  69.          header_comment = c.header_comment;
  70.          count = c.count
  71.       end;
  72.  
  73. feature
  74.  
  75.    count: INTEGER is
  76.       do
  77.          if first_one = Void then
  78.          elseif remainder /= Void then
  79.             Result := remainder.upper + 2;
  80.          else
  81.             Result := 1;
  82.          end;
  83.       end;
  84.  
  85.    first: INSTRUCTION is
  86.       require
  87.          count >= 1
  88.       do
  89.          Result := first_one;
  90.       ensure
  91.          Result /= Void
  92.       end;
  93.  
  94.    item(i: INTEGER): INSTRUCTION is
  95.       require
  96.          i.in_range(1,count)
  97.       do
  98.          if i = 1 then
  99.             Result := first_one;
  100.          else
  101.             Result := remainder.item(i - 2);
  102.          end;
  103.       end;
  104.  
  105.    start_position: POSITION is
  106.       do
  107.          if count > 0 then
  108.             Result := first_one.start_position;
  109.          end;
  110.       end;
  111.  
  112.    run_class: RUN_CLASS is
  113.       do
  114.          Result := current_type.run_class;
  115.       end;
  116.  
  117.    afd_check is
  118.       local
  119.          i: INTEGER;
  120.       do
  121.          from
  122.             i := count;
  123.          until
  124.             i = 0
  125.          loop
  126.             item(i).afd_check;
  127.             i := i - 1;
  128.          end;
  129.       end;
  130.  
  131.    compile_to_c is
  132.       local
  133.          i, c: INTEGER;
  134.          instruction: INSTRUCTION;
  135.          need_se_tmp: BOOLEAN;
  136.          no_check: BOOLEAN;
  137.       do
  138.      cpp.one_more_instruction_generated;
  139.          from
  140.             no_check := run_control.no_check;
  141.             i := 1;
  142.             c := count;
  143.          until
  144.             i > c
  145.          loop
  146.             instruction := item(i);
  147.             instruction.collect_c_tmp;
  148.             need_se_tmp := cpp.se_tmp_open_declaration;
  149.             instruction.compile_to_c;
  150.         cpp.one_more_instruction_generated;
  151.             if need_se_tmp then
  152.                cpp.se_tmp_close_declaration;
  153.             end;
  154.             i := i + 1;
  155.          end;
  156.       end;
  157.  
  158.    c2jvm: BOOLEAN is
  159.          -- Result is false when no byte code is produced.
  160.       local
  161.          pc: INTEGER;
  162.       do
  163.          pc := code_attribute.program_counter;
  164.          compile_to_jvm;
  165.          Result := pc /= code_attribute.program_counter;
  166.       end;
  167.  
  168.    compile_to_jvm is
  169.       local
  170.          i, c: INTEGER;
  171.          instruction: INSTRUCTION;
  172.          trace: BOOLEAN;
  173.          ca: like code_attribute;
  174.       do
  175.          from
  176.             c := count;
  177.             ca := code_attribute;
  178.             trace := run_control.trace;
  179.             i := 1;
  180.          until
  181.             i > c
  182.          loop
  183.             instruction := item(i);
  184.             if trace then
  185.                ca.se_trace(current_type,instruction.start_position);
  186.             end;
  187.             instruction.compile_to_jvm;
  188.             i := i + 1;
  189.          end;
  190.       end;
  191.  
  192.    use_current: BOOLEAN is
  193.       local
  194.          i: INTEGER;
  195.       do
  196.          from
  197.             i := count;
  198.          until
  199.             Result or else i = 0
  200.          loop
  201.             Result := item(i).use_current;
  202.             i := i - 1;
  203.          end;
  204.       end;
  205.  
  206.    stupid_switch(r: ARRAY[RUN_CLASS]): BOOLEAN is
  207.       local
  208.          i: INTEGER;
  209.       do
  210.          from
  211.             Result := true
  212.             i := count;
  213.          until
  214.             not Result or else i = 0
  215.          loop
  216.             Result := item(i).stupid_switch(r);
  217.             i := i - 1;
  218.          end;
  219.       end;
  220.  
  221.    is_pre_computable: BOOLEAN is
  222.       local
  223.          i: INTEGER;
  224.       do
  225.          from
  226.             i := count;
  227.             Result := true;
  228.          until
  229.             not Result or else i = 0
  230.          loop
  231.             Result := item(i).is_pre_computable;
  232.             i := i - 1;
  233.          end;
  234.       end;
  235.  
  236.    to_runnable(ct: TYPE): like Current is
  237.       require
  238.          ct.run_type = ct;
  239.          nb_errors = 0
  240.       local
  241.          i: INTEGER;
  242.          i1, i2: INSTRUCTION;
  243.       do
  244.          if first_one = Void then
  245.             Result := Current;
  246.          elseif current_type = Void then
  247.             current_type := ct;
  248.             from
  249.                i := count;
  250.             until
  251.                i = 0
  252.             loop
  253.                i1 := item(i);
  254.                i2 := i1.to_runnable(ct);
  255.                if nb_errors > 0 then
  256.                   eh.append("Bad instruction (when interpreted in ");
  257.                   eh.append(current_type.written_mark);
  258.                   eh.add_position(i1.start_position);
  259.                   fatal_error(").");
  260.                else
  261.                   put(i2,i);
  262.                end;
  263.                i := i - 1;
  264.             end;
  265.             Result := Current;
  266.          else
  267.             !!Result.from_compound(Current);
  268.             Result := Result.to_runnable(ct);
  269.          end;
  270.       ensure
  271.          Result /= Void
  272.       end;
  273.  
  274.    pretty_print is
  275.       require
  276.          fmt.indent_level >= 2;
  277.       local
  278.          i, c: INTEGER;
  279.       do
  280.          c := count
  281.          fmt.level_incr;
  282.          fmt.indent;
  283.          if header_comment /= Void then
  284.             header_comment.pretty_print;
  285.          end;
  286.          from
  287.             i := 1;
  288.          until
  289.             i > c
  290.          loop
  291.             fmt.set_semi_colon_flag(true);
  292.             if fmt.zen_mode and then i = c then
  293.                fmt.set_semi_colon_flag(false);
  294.             end;
  295.             fmt.indent;
  296.             item(i).pretty_print;
  297.             i := i + 1;
  298.          end;
  299.          fmt.level_decr;
  300.       ensure
  301.          fmt.indent_level = old fmt.indent_level;
  302.       end;
  303.  
  304.    empty_or_null_body: BOOLEAN is
  305.       do
  306.          Result := first_one = Void;
  307.       end;
  308.  
  309. feature {NONE}
  310.  
  311.    put(i: INSTRUCTION; idx: INTEGER) is
  312.       require
  313.          i /= Void;
  314.          idx.in_range(1,count)
  315.       do
  316.          if idx = 1 then
  317.             first_one := i;
  318.          else
  319.             remainder.put(i,idx - 2);
  320.          end;
  321.       end;
  322.  
  323. invariant
  324.  
  325.    header_comment /= Void or else first_one /= Void;
  326.  
  327.    remainder /= Void implies first_one /= Void;
  328.  
  329. end -- COMPOUND
  330.  
  331.